#ifndef __SIMNAND_H__
#define __SIMNAND_H__

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#define DEFAULT_PORT   6789
#define DEFAULT_IP     "192.168.1.12"

#define DEFAULT_PATH   "/tmp"

#define MAXLINE   5
#define OPEN_MAX  100
#define LISTENQ   20
#define SERV_PORT 5000
#define MAX_EPOLL_COUNT  32
#define MAX_EPOLL_EVENT  32
#define MAX_EPOLL_TIMEOUT 500

#define MAX_CHANNEL_COUNT  8
#define MAX_PATH_LENGTH  256
#define MAX_IP_LENGTH    12

#define SECTOR_SIZE  (4096)
#define PAGE_SIZE    (4*4096)
#define BLOCK_SIZE   (479)
#define BANK_SIZE    (4)
#define DIE_SIZE     (4)

#define DIE_OFFSET(bank, block, page)  ( (bank)*BANK_SIZE + (block)*BLOCK_SIZE + (page)*PAGE_SIZE )

enum CMD_TYPE {
    CMD_READ = 1,
    CMD_WRITE,
    CMD_ERASE,
};

enum CHANNEL_NUM {
    CHANNEL0 = 0,
    CHANNEL1,
    CHANNEL2,
    CHANNEL3,
    CHANNEL4,
    CHANNEL5,
    CHANNEL6,
    CHANNEL7,
};


struct tiein {

};

struct tieout {

};

struct payload {
    union {
        struct tiein in;
        struct tieout out;
    } tie;

    int cmd_type;
    int channel;
    int die;
    int bank;
    int block;
    int page;

    int size;
    char* pbuf;
};


struct simnand_device {
    pthread_t pid[MAX_CHANNEL_COUNT];

    int channelcnt;
    int diecnt;
    int planecnt;
    int blockcnt;
    int pagesize;
    int sectorsize;
    int port;
    char path[MAX_PATH_LENGTH+1];
    char ip[MAX_IP_LENGTH+1];
};


struct simnand_inst {
    int chid;
    char pchpath[MAX_PATH_LENGTH+50];
    FILE *fp;

    char* ip;
    int portnum;

    struct epoll_event events[20];
    int epfd;
    int socketfd;

    struct simnand_device *pdev;

    struct payload *ploadbuf;
};



void* simnand_inst_server(void* param);
int simnand_ops(int sockfd, struct simnand_inst *pinst, char *pbuf, int count);
void printids(const char *s);


#endif
